home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / WPrefs.app / Menu.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-04-02  |  39.7 KB  |  1,521 lines

  1. /* Menu.c- menu definition
  2.  * 
  3.  *  WPrefs - Window Maker Preferences Program
  4.  * 
  5.  *  Copyright (c) 1998 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23.  
  24. #include "WPrefs.h"
  25. #include <assert.h>
  26. #include <ctype.h>
  27.  
  28. #include <X11/keysym.h>
  29.  
  30. typedef struct _Panel {
  31.     WMFrame *frame;
  32.     char *sectionName;
  33.  
  34.     char *description;
  35.  
  36.     CallbackRec callbacks;
  37.     WMWindow *win;
  38.     
  39.     WMPopUpButton *cmd1P;
  40.     WMPopUpButton *cmd2P;
  41.     
  42.     WMTextField *tit1T;
  43.     WMTextField *tit2T;
  44.     
  45.     WMBrowser *browser;
  46.     
  47.     WMFrame *labF;
  48.     WMTextField *labT;
  49.     
  50.     WMFrame *cmdF;
  51.     WMPopUpButton *cmdP;
  52.  
  53.     WMButton *noconfirmB;
  54.  
  55.     WMFrame *proF;
  56.     WMTextField *proT;
  57.     WMLabel *infoL;
  58.  
  59.     WMFrame *pathF;
  60.     WMTextField *pathT;
  61.     WMLabel *pathL;
  62.  
  63.     WMFrame *shoF;
  64.     WMTextField *shoT;
  65.     WMButton *shoB;
  66.     
  67.     WMButton *guruB;
  68.  
  69.     /**/
  70.     proplist_t menu;
  71.     proplist_t editedItem;
  72.     
  73.     proplist_t itemClipboard;           /* for copy/paste */
  74.  
  75.     char capturing;               /* shortcut capture */
  76.     char unsaved;               /* if there are unsaved changes */
  77.     char dontSave;
  78.     char scrolledBrowser;
  79. } _Panel;
  80.  
  81.  
  82.  
  83. #define ICON_FILE    "menus"
  84.  
  85.  
  86.  
  87. extern char *OpenMenuGuru(WMWindow *mainWindow);
  88.  
  89. extern Bool AskMenuCopy(WMWindow *wwin);
  90.  
  91.  
  92. /* must match the indexes of the commands popup */
  93. enum {
  94.     CAddCommand = 0,
  95.     CAddSubmenu = 1,
  96.     CAddExternal = 2,
  97.     CAddWorkspace = 3,
  98.     CRemove = 4,
  99.     CCut = 5,
  100.     CCopy = 6,
  101.     CPaste = 7
  102. };
  103.  
  104.  
  105. enum {
  106.     CpExec = 0,
  107.     CpShExec = 1,
  108.     CpArrange = 2,
  109.     CpHide = 3,
  110.     CpShow = 4,
  111.     CpExit = 5,
  112.     CpShutdown = 6,
  113.     CpRestart = 7,
  114.     CpRestartWM = 8,
  115.     CpSaveSession = 9,
  116.     CpClearSession = 10,
  117.     CpRefresh = 11,
  118.     CpInfo = 12,
  119.     CpLegal = 13
  120. };
  121.  
  122. enum {
  123.     TNothing,
  124.     TExec,
  125.     TShExec,
  126.     TSimpleCommand,
  127.     TRestart,
  128.     TRestartWM,
  129.     TExit,
  130.     TExternalMenu,
  131.     TWSMenu
  132. };
  133.  
  134.  
  135.  
  136. static void showData(_Panel *panel);
  137.  
  138. static void fillBrowser(WMBrowserDelegate *self, WMBrowser *bPtr, int column,
  139.                WMList *list);
  140.  
  141. static void scrolledBrowser(WMBrowserDelegate *self, WMBrowser *sender);
  142.  
  143. static WMBrowserDelegate browserDelegate = {
  144.     NULL, /* data */
  145.     fillBrowser, /* createRowsForColumn */
  146.     NULL, /* titleOfColumn */
  147.     scrolledBrowser, /* didScroll */
  148.     NULL  /* willScroll */
  149. };
  150.  
  151.  
  152. static Bool
  153. isMenu(proplist_t item)
  154. {
  155.     if (PLGetNumberOfElements(item)==1)
  156.     return True;
  157.     
  158.     return PLIsArray(PLGetArrayElement(item, 1));
  159. }
  160.  
  161.  
  162. static void
  163. splitOpenMenuParameter(char *str, char **dirs, char **prog)
  164. {
  165.     char *p;
  166.     
  167.     if (!(p = strstr(str, " WITH "))) {
  168.     *dirs = wstrdup(str);
  169.     *prog = NULL;
  170.     } else {
  171.     int i, j;
  172.        
  173.     i = strlen(str);
  174.     j = strlen(p);
  175.     *dirs = wmalloc(i-j+1);
  176.     strncpy(*dirs, str, i-j+1);
  177.     (*dirs)[i-j] = 0;
  178.  
  179.     p += 6;
  180.     while (isspace(*p)) p++;
  181.     if (*p!=0) {
  182.         *prog = wmalloc(j);
  183.         strcpy(*prog, p);
  184.     } else {
  185.         *prog = NULL;
  186.     }
  187.     }
  188. }
  189.  
  190.  
  191. static void
  192. changeItemTitle(proplist_t item, char *title)
  193. {
  194.     proplist_t tmp;
  195.     
  196.     tmp = PLGetArrayElement(item, 0);
  197.     PLRelease(tmp);
  198.     PLRemoveArrayElement(item, 0);
  199.     PLInsertArrayElement(item, title?PLMakeString(title):PLMakeString(""), 0);
  200. }
  201.  
  202.  
  203. static void
  204. removeParameter(proplist_t item)
  205. {
  206.     proplist_t tmp;
  207.     int index;
  208.     
  209.     if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) {
  210.     index = 4;
  211.     } else {
  212.     index = 2;
  213.     }
  214.     tmp = PLGetArrayElement(item, index);
  215.     PLRemoveArrayElement(item, index);
  216.     if (tmp)
  217.     PLRelease(tmp);
  218. }
  219.  
  220.  
  221. static void
  222. changeItemParameter(proplist_t item, char *param)
  223. {
  224.     proplist_t tmp;
  225.     int index;
  226.     
  227.     if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) {
  228.     index = 4;
  229.     } else {
  230.     index = 2;
  231.     }
  232.     tmp = PLGetArrayElement(item, index);
  233.     PLRemoveArrayElement(item, index);
  234.     PLRelease(tmp);
  235.     tmp = param?PLMakeString(param):PLMakeString("");
  236.     PLInsertArrayElement(item, tmp, index);
  237. }
  238.  
  239.  
  240. static void
  241. changeItemShortcut(proplist_t item, char *shortcut)
  242. {
  243.     proplist_t tmp;
  244.  
  245.     if (strcmp(PLGetString(PLGetArrayElement(item, 1)), "SHORTCUT")==0) {
  246.     if (shortcut) {
  247.         tmp = PLGetArrayElement(item, 2);
  248.         PLRemoveArrayElement(item, 2);
  249.         PLRelease(tmp);
  250.         PLInsertArrayElement(item, PLMakeString(shortcut), 2);
  251.     } else {
  252.         /* remove SHORTCUT keyword */
  253.         tmp = PLGetArrayElement(item, 1);
  254.         PLRemoveArrayElement(item, 1);
  255.         PLRelease(tmp);
  256.         /* remove the shortcut */
  257.         tmp = PLGetArrayElement(item, 1);
  258.         PLRemoveArrayElement(item, 1);
  259.         PLRelease(tmp);
  260.     }
  261.     } else {
  262.     if (shortcut) {
  263.         PLInsertArrayElement(item, PLMakeString("SHORTCUT"), 1);
  264.         PLInsertArrayElement(item, PLMakeString(shortcut), 2);        
  265.     } else {
  266.         /* do nothing */
  267.     }
  268.     }
  269. }
  270.  
  271.  
  272. static void
  273. changeItemCommand(proplist_t item, char *command)
  274. {
  275.     proplist_t tmp;
  276.  
  277.     tmp = PLGetArrayElement(item, 1);
  278.     if (strcmp(PLGetString(tmp), "SHORTCUT")==0) {
  279.     PLRelease(tmp);
  280.     PLRemoveArrayElement(item, 3);
  281.     PLInsertArrayElement(item, PLMakeString(command), 3);
  282.     } else {
  283.     PLRelease(tmp);
  284.     PLRemoveArrayElement(item, 1);
  285.     PLInsertArrayElement(item, PLMakeString(command), 1);
  286.     }
  287. }
  288.  
  289.  
  290. static char*
  291. getItemTitle(proplist_t item)
  292. {
  293.     return PLGetString(PLGetArrayElement(item, 0));
  294. }
  295.  
  296.  
  297. static char*
  298. getItemParameter(proplist_t item)
  299. {
  300.     proplist_t tmp;
  301.  
  302.     tmp = PLGetArrayElement(item, 1);
  303.     if (strcmp(PLGetString(tmp), "SHORTCUT")==0) {
  304.     tmp = PLGetArrayElement(item, 4);
  305.     return tmp ? PLGetString(tmp) : NULL;
  306.     } else {
  307.     tmp = PLGetArrayElement(item, 2);
  308.     return tmp ? PLGetString(tmp) : NULL;
  309.     }
  310. }
  311.  
  312.  
  313.  
  314. static char*
  315. getItemShortcut(proplist_t item)
  316. {
  317.     proplist_t tmp;
  318.  
  319.     tmp = PLGetArrayElement(item, 1);
  320.     if (strcmp(PLGetString(tmp), "SHORTCUT")==0) {
  321.     return PLGetString(PLGetArrayElement(item, 2));
  322.     } else {
  323.     return NULL;
  324.     }
  325. }
  326.  
  327.  
  328.  
  329. static char*
  330. getItemCommand(proplist_t item)
  331. {
  332.     proplist_t tmp;
  333.     char *str;
  334.  
  335.     tmp = PLGetArrayElement(item, 1);
  336.     if (!tmp)
  337.     return "";
  338.     if (strcmp(PLGetString(tmp), "SHORTCUT")==0) {
  339.     str = PLGetString(PLGetArrayElement(item,3));
  340.     } else {
  341.     str = PLGetString(tmp);
  342.     }
  343.     return str;
  344. }
  345.  
  346.  
  347.  
  348. static proplist_t
  349. getSubmenuInColumn(_Panel *panel, int column)
  350. {
  351.     proplist_t parent;
  352.     proplist_t submenu;
  353.     WMList *list;
  354.     int r;
  355.  
  356.     if (column == 0) {
  357.     return panel->menu;
  358.     }
  359.     if (column >= WMGetBrowserNumberOfColumns(panel->browser))
  360.     return NULL;
  361.  
  362.     list = WMGetBrowserListInColumn(panel->browser, column - 1);
  363.     assert(list != NULL);
  364.  
  365.     r = WMGetListSelectedItemRow(list);
  366.  
  367.     parent = getSubmenuInColumn(panel, column - 1);
  368.  
  369.     assert(parent != NULL);
  370.  
  371.     submenu = PLGetArrayElement(parent, r + 1);
  372.  
  373.     return submenu;
  374. }
  375.  
  376.  
  377. static void
  378. updateForItemType(_Panel *panel, int type)
  379. {
  380.     if (type==TNothing) {
  381.     WMUnmapWidget(panel->labF);
  382.     } else {
  383.     WMMapWidget(panel->labF);
  384.     }
  385.     if (type==TExternalMenu || type==TNothing) {
  386.     WMUnmapWidget(panel->cmdF);
  387.     } else {
  388.     WMMapWidget(panel->cmdF);
  389.     }
  390.     if (type==TNothing || type==TWSMenu || type==TExternalMenu) {
  391.     WMUnmapWidget(panel->shoF);
  392.     } else {
  393.     WMMapWidget(panel->shoF);
  394.     }
  395.     if (type==TExec || type == TShExec || type==TRestart 
  396.     || type==TExternalMenu) {
  397.     WMMapWidget(panel->proF);
  398.     } else {
  399.     WMUnmapWidget(panel->proF);
  400.     }
  401.     if (type==TExternalMenu) {
  402.     WMMapWidget(panel->pathF);
  403.     } else {
  404.     WMUnmapWidget(panel->pathF);
  405.     }
  406.     if (type==TExit) {
  407.     WMMapWidget(panel->noconfirmB);
  408.     } else {
  409.     WMUnmapWidget(panel->noconfirmB);
  410.     }
  411.     if (type==TWSMenu) {
  412.     WMMapWidget(panel->infoL);
  413.     } else {
  414.     WMUnmapWidget(panel->infoL);
  415.     }
  416.     if (type==TExternalMenu) {
  417.     WMMapWidget(panel->guruB);
  418.     } else {
  419.     WMUnmapWidget(panel->guruB);
  420.     }
  421.     if (type == TRestart) {
  422.     WMSetFrameTitle(panel->proF, _("Window Manager"));
  423.     } else if (type == TExternalMenu) {
  424.     WMSetFrameTitle(panel->proF, _("Program to Open Files"));
  425.     } else if (type == TShExec) {
  426.     WMSetFrameTitle(panel->proF, _("Command to Execute"));
  427.     } else {
  428.     WMSetFrameTitle(panel->proF, _("Program to Run"));
  429.     }
  430. }
  431.  
  432.  
  433. proplist_t
  434. getItemOfSelectedEntry(WMBrowser *bPtr)
  435. {
  436.     proplist_t item;
  437.     proplist_t menu;
  438.     int i;
  439.  
  440.     i = WMGetBrowserSelectedColumn(bPtr);
  441.     menu = getSubmenuInColumn((_Panel*)WMGetHangedData(bPtr), i);
  442.  
  443.     i = WMGetBrowserSelectedRowInColumn(bPtr, i);
  444.     item = PLGetArrayElement(menu, i+1);
  445.  
  446.     return item;
  447. }
  448.  
  449.  
  450. static void
  451. performCommand(WMWidget *w, void *data)
  452. {
  453.     _Panel *panel = (_Panel*)data;
  454.     WMPopUpButton *pop = (WMPopUpButton*)w;
  455.     proplist_t menuItem = NULL;
  456.     proplist_t menu;
  457.     int column;
  458.     int row;
  459.     static int cmdIndex=0;
  460.     char *title = NULL;
  461.     Bool removed = False;
  462.  
  463.     column = WMGetBrowserFirstVisibleColumn(panel->browser);
  464.     if (pop == panel->cmd2P) {
  465.     column++;
  466.     }
  467.  
  468.     if (column >= WMGetBrowserNumberOfColumns(panel->browser))
  469.     return;
  470.  
  471.     menu = getSubmenuInColumn(panel, column);
  472.     
  473.     row = WMGetBrowserSelectedRowInColumn(panel->browser, column);
  474.  
  475.     switch (WMGetPopUpButtonSelectedItem(pop)) {
  476.      case CAddCommand:
  477.     title = wmalloc(strlen(_("New Command %i"))+6);
  478.     sprintf(title, _("New Command %i"), cmdIndex++);
  479.     menuItem = PLMakeArrayFromElements(PLMakeString(title),
  480.                        PLMakeString("EXEC"),
  481.                        PLMakeString(""),
  482.                        NULL);
  483.     break;
  484.      case CAddSubmenu:
  485.     title = wstrdup(_("New Submenu"));
  486.     menuItem = PLMakeArrayFromElements(PLMakeString(title),
  487.                        NULL);
  488.     break;
  489.      case CAddExternal:
  490.     title = wstrdup(_("External Menu"));
  491.     menuItem = PLMakeArrayFromElements(PLMakeString(title),
  492.                        PLMakeString("OPEN_MENU"),
  493.                        PLMakeString(""),
  494.                        NULL);
  495.     break;
  496.      case CAddWorkspace:
  497.     title = wstrdup(_("Workspaces"));
  498.     menuItem = PLMakeArrayFromElements(PLMakeString(title),
  499.                        PLMakeString("WORKSPACE_MENU"),
  500.                        NULL);
  501.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, False);
  502.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, False);
  503.     break;
  504.      case CRemove:
  505.     if (row < 0)
  506.         return;
  507.     panel->scrolledBrowser = 0;
  508.     WMRemoveBrowserItem(panel->browser, column, row);
  509.     menuItem = PLGetArrayElement(menu, row+1);
  510.     if (strcmp(getItemCommand(menuItem), "WORKSPACE_MENU")==0) {
  511.         WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True);
  512.         WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True);
  513.     }
  514.     PLRemoveArrayElement(menu, row+1);
  515.     PLRelease(menuItem);
  516.     updateForItemType(panel, TNothing);
  517.     panel->editedItem = NULL;
  518.     panel->unsaved = 1;
  519.  
  520.     if (pop == panel->cmd1P && !panel->scrolledBrowser) {
  521.         WMSetTextFieldText(panel->tit2T, NULL);
  522.     }
  523.  
  524.     removed = True;
  525.     return;
  526.      case CCut:
  527.     if (row < 0)
  528.         return;
  529.     if (panel->itemClipboard 
  530.         && strcmp(getItemCommand(panel->itemClipboard), "WORKSPACE_MENU")==0){
  531.         WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True);
  532.         WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True);
  533.     }
  534.     if (panel->itemClipboard)
  535.         PLRelease(panel->itemClipboard);
  536.     WMRemoveBrowserItem(panel->browser, column, row);
  537.     menuItem = PLGetArrayElement(menu, row+1);
  538.     PLRemoveArrayElement(menu, row+1);
  539.     updateForItemType(panel, TNothing);
  540.     
  541.     panel->itemClipboard = menuItem;
  542.  
  543.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, True);
  544.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, True);
  545.     panel->unsaved = 1;
  546.     removed = True;
  547.     return;    
  548.      case CCopy:
  549.     if (row < 0)
  550.         return;
  551.     if (panel->itemClipboard 
  552.         && strcmp(getItemCommand(panel->itemClipboard), "WORKSPACE_MENU")==0){
  553.         WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, True);
  554.         WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, True);
  555.     }
  556.     if (panel->itemClipboard)
  557.         PLRelease(panel->itemClipboard);
  558.     panel->itemClipboard = NULL;
  559.     menuItem = PLGetArrayElement(menu, row+1);
  560.     if (strcmp(getItemCommand(menuItem), "WORKSPACE_MENU")==0)
  561.         return;
  562.     panel->itemClipboard = PLDeepCopy(menuItem);
  563.     
  564.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, True);
  565.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, True);
  566.     return;
  567.      case CPaste:
  568.     menuItem = panel->itemClipboard;
  569.     title = wstrdup(getItemTitle(menuItem));
  570.     panel->itemClipboard = NULL;
  571.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, False);
  572.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, False);    
  573.     break;
  574.     }
  575.  
  576.  
  577.     {
  578.     int i, j;
  579.     WMList *list;
  580.     
  581.     list = WMGetBrowserListInColumn(panel->browser, 0);
  582.     for (i = 0; i < WMGetListNumberOfRows(list); i++) {
  583.         WMListItem *item =WMGetListItem(list, i);
  584.         if (!item)
  585.         printf("%i empty\n", i);
  586.         else
  587.         puts(item->text);
  588.     }
  589.     
  590.     }
  591.     if (row>=0) row++;
  592.     WMInsertBrowserItem(panel->browser, column, row, title, isMenu(menuItem));
  593.     if (row<0)
  594.     PLAppendArrayElement(menu, menuItem);
  595.     else
  596.     PLInsertArrayElement(menu, menuItem, row+1);
  597.     free(title);
  598.     
  599.     
  600.     panel->unsaved = 1;
  601.     
  602.     if (removed) {
  603.     if (pop == panel->cmd1P) {
  604.         WMSetTextFieldText(panel->tit2T, NULL);
  605.     }
  606.     }
  607. }
  608.  
  609.  
  610. static void
  611. browserClick(WMWidget *w, void *data)
  612. {
  613.     _Panel *panel = (_Panel*)data;
  614.     proplist_t item;
  615.     char *command;
  616.     
  617.     /* stop shortcut capture */
  618.     panel->capturing = 0;
  619.  
  620.     item = getItemOfSelectedEntry(panel->browser);
  621.  
  622.     panel->editedItem = item;
  623.  
  624.     /* set title */
  625.     WMSetTextFieldText(panel->labT, getItemTitle(item));
  626.  
  627.     if (isMenu(item)) {
  628.     updateForItemType(panel, TNothing);
  629.  
  630.     WMSetPopUpButtonEnabled(panel->cmd2P, True);
  631.     return;
  632.     } else {
  633.     int column = WMGetBrowserSelectedColumn(panel->browser);
  634.  
  635.     if (column == WMGetBrowserNumberOfColumns(panel->browser)-1
  636.         && column > 0)
  637.         WMSetPopUpButtonEnabled(panel->cmd2P, True);
  638.     else
  639.         WMSetPopUpButtonEnabled(panel->cmd2P, False);
  640.  
  641.     if (column==WMGetBrowserFirstVisibleColumn(panel->browser)) {
  642.         /* second column is empty, because selected item is not a submenu */
  643.         WMSetTextFieldText(panel->tit2T, NULL);
  644.     }
  645.     }
  646.  
  647.     command = getItemCommand(item);
  648.  
  649.     WMSetTextFieldText(panel->shoT, getItemShortcut(item));
  650.     
  651.     if (strcmp(command, "OPEN_MENU")==0) {
  652.     char *p, *c;
  653.     
  654.     splitOpenMenuParameter(getItemParameter(item), &p, &c);
  655.     WMSetTextFieldText(panel->pathT, p);
  656.     WMSetTextFieldText(panel->proT, c);
  657.     if (p)
  658.         free(p);
  659.     if (c)
  660.         free(c);
  661.     updateForItemType(panel, TExternalMenu);
  662.     } else if (strcmp(command, "EXEC")==0) {
  663.     WMSetTextFieldText(panel->proT, getItemParameter(item));
  664.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpExec);
  665.     updateForItemType(panel, TExec);
  666.     } else if (strcmp(command, "SHEXEC")==0) {
  667.     WMSetTextFieldText(panel->proT, getItemParameter(item));
  668.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpShExec);
  669.     updateForItemType(panel, TShExec);
  670.     } else if (strcmp(command, "WORKSPACE_MENU")==0) {
  671.     updateForItemType(panel, TWSMenu);
  672.     } else if (strcmp(command, "EXIT")==0) {
  673.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpExit);
  674.     updateForItemType(panel, TExit);
  675.     } else if (strcmp(command, "SHUTDOWN")==0) {
  676.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpShutdown);
  677.     updateForItemType(panel, TExit);
  678.     } else if (strcmp(command, "RESTARTW")==0) {
  679.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpRestartWM);
  680.     updateForItemType(panel, TRestartWM);
  681.     } else if (strcmp(command, "RESTART")==0) {
  682.     WMSetPopUpButtonSelectedItem(panel->cmdP, CpRestart);
  683.     WMSetTextFieldText(panel->proT, getItemParameter(item));
  684.     updateForItemType(panel, TRestart);
  685.     } else {
  686.     /* simple commands */
  687.     if (strcmp(command, "ARRANGE_ICONS")==0)
  688.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpArrange);
  689.     else if (strcmp(command, "HIDE_OTHERS")==0)
  690.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpHide);
  691.     else if (strcmp(command, "SHOW_ALL")==0)
  692.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpShow);
  693.     else if (strcmp(command, "SAVE_SESSION")==0)
  694.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpSaveSession);
  695.     else if (strcmp(command, "CLEAR_SESSION")==0)
  696.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpClearSession);
  697.     else if (strcmp(command, "REFRESH")==0)
  698.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpRefresh);
  699.     else if (strcmp(command, "INFO_PANEL")==0)
  700.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpInfo);
  701.     else if (strcmp(command, "LEGAL_PANEL")==0)
  702.         WMSetPopUpButtonSelectedItem(panel->cmdP, CpLegal);
  703.     updateForItemType(panel, TSimpleCommand);
  704.     }
  705. }
  706.  
  707.  
  708.  
  709. static void
  710. fillBrowser(WMBrowserDelegate *self, WMBrowser *bPtr, int column, WMList *list)
  711. {
  712.     _Panel *panel = (_Panel*)WMGetHangedData(bPtr);
  713.     proplist_t menuItem;
  714.     proplist_t menuList = NULL;
  715.     int i;
  716.  
  717.  
  718.     menuList = getSubmenuInColumn(panel, column);
  719.     assert(menuList != NULL);
  720.  
  721.     if (column > WMGetBrowserFirstVisibleColumn(bPtr)) {
  722.     WMSetTextFieldText(panel->tit2T, getItemTitle(menuList));
  723.     } else {
  724.     WMSetTextFieldText(panel->tit1T, getItemTitle(menuList));
  725.     }
  726.  
  727.     for (i=1; i<PLGetNumberOfElements(menuList); i++) {
  728.     menuItem = PLGetArrayElement(menuList, i);
  729.     WMInsertBrowserItem(bPtr, column, -1, getItemTitle(menuItem),
  730.                 isMenu(menuItem));
  731.     }
  732. }
  733.  
  734.  
  735.  
  736.  
  737. static void
  738. changedItem(void *observerData, WMNotification *notification)
  739. {
  740.     _Panel *panel = (_Panel*)observerData;
  741.     WMTextField *t = (WMTextField*)WMGetNotificationObject(notification);
  742.     proplist_t item = panel->editedItem;
  743.     WMList *list;
  744.     WMListItem *litem;
  745.     char *command;
  746.     char *str;
  747.  
  748.  
  749.     if (!item)
  750.     return;
  751.  
  752.     panel->unsaved = 1;
  753.     if (!isMenu(item)) {
  754.     command = getItemCommand(item);
  755.     
  756.     if (t == panel->shoT) {
  757.         str = WMGetTextFieldText(t);
  758.         if (strlen(str)==0) {
  759.         free(str);
  760.         str = NULL;
  761.         }
  762.         changeItemShortcut(item, str);
  763.         if (str)
  764.         free(str);        
  765.     } else if (t == panel->labT) {
  766.         int column;
  767.  
  768.         str = WMGetTextFieldText(t);
  769.         if (!str)
  770.         str = wstrdup("");
  771.         changeItemTitle(item, str);
  772.         column = WMGetBrowserSelectedColumn(panel->browser);
  773.         list = WMGetBrowserListInColumn(panel->browser, column);
  774.         litem = WMGetListSelectedItem(list);
  775.         
  776.         free(litem->text);
  777.         litem->text = str;
  778.     
  779.         WMRedisplayWidget(list);
  780.     } else if (strcmp(command, "EXEC")==0
  781.            || strcmp(command, "SHEXEC")==0
  782.            || strcmp(command, "RESTART")==0) {
  783.         if (t == panel->proT) {
  784.         str = WMGetTextFieldText(t);
  785.  
  786.         changeItemParameter(item, str);
  787.  
  788.         free(str);
  789.         }
  790.     } else if (strcmp(command, "OPEN_MENU")==0) {
  791.         char *text;
  792.         char *str2;
  793.         
  794.         str = WMGetTextFieldText(panel->pathT);
  795.         str2 = WMGetTextFieldText(panel->proT);
  796.         text = wmalloc(strlen(str)+strlen(str2)+16);
  797.         strcpy(text, str);
  798.         free(str);
  799.         if (strlen(str2)>0) {
  800.         strcat(text, " WITH ");
  801.         strcat(text, str2);
  802.         }
  803.         free(str2);
  804.         changeItemParameter(item, text);
  805.         free(text);
  806.     }
  807.     }
  808. }
  809.  
  810.  
  811. static void
  812. changedTitle(void *observerData, WMNotification *notification)
  813. {
  814.     _Panel *panel = (_Panel*)observerData;
  815.     WMTextField *t = (WMTextField*)WMGetNotificationObject(notification);
  816.     proplist_t menu;
  817.     WMList *list;
  818.     int column;
  819.     char *txt;
  820.  
  821.     column = WMGetBrowserFirstVisibleColumn(panel->browser);
  822.     if (panel->tit2T == t)
  823.     column++;
  824.     
  825.     menu = getSubmenuInColumn(panel, column);
  826.     if (!menu)
  827.     return;
  828.  
  829.     txt = WMGetTextFieldText(t);
  830.     changeItemTitle(menu, txt);
  831.     
  832.     if (column > 0) {
  833.     WMListItem *litem;
  834.     
  835.     list = WMGetBrowserListInColumn(panel->browser, column-1);
  836.     litem = WMGetListSelectedItem(list);
  837.     
  838.     free(litem->text);
  839.     litem->text = txt;
  840.     
  841.     WMRedisplayWidget(list);
  842.     } else {
  843.     free(txt);
  844.     }
  845.     panel->unsaved = 1;
  846. }
  847.  
  848.  
  849. static void
  850. changedCommand(WMWidget *w, void *data)
  851. {
  852.     _Panel *panel = (_Panel*)data;
  853.     int i;
  854.     char *tmp;
  855.  
  856.     panel->unsaved = 1;
  857.     i = WMGetPopUpButtonSelectedItem(panel->cmdP);
  858.     changeItemParameter(panel->editedItem, "");
  859.     switch (i) {
  860.      case CpExec:
  861.     if (strcmp(getItemCommand(panel->editedItem), "EXEC")!=0) {
  862.         changeItemCommand(panel->editedItem, "EXEC");
  863.         tmp = WMGetTextFieldText(panel->proT);
  864.         changeItemParameter(panel->editedItem, tmp);
  865.         free(tmp);
  866.         updateForItemType(panel, TExec);
  867.     }
  868.     break;
  869.      case CpShExec:
  870.     if (strcmp(getItemCommand(panel->editedItem), "SHEXEC")!=0) {
  871.         changeItemCommand(panel->editedItem, "SHEXEC");
  872.         tmp = WMGetTextFieldText(panel->proT);
  873.         changeItemParameter(panel->editedItem, tmp);
  874.         free(tmp);
  875.         updateForItemType(panel, TShExec);
  876.     }
  877.     break;
  878.      case CpArrange:
  879.     if (strcmp(getItemCommand(panel->editedItem), "ARRANGE_ICONS")!=0) {
  880.         changeItemCommand(panel->editedItem, "ARRANGE_ICONS");
  881.         updateForItemType(panel, TSimpleCommand);
  882.     }
  883.     break;
  884.      case CpHide:
  885.     if (strcmp(getItemCommand(panel->editedItem), "HIDE_OTHERS")!=0) {
  886.         changeItemCommand(panel->editedItem, "HIDE_OTHERS");
  887.         updateForItemType(panel, TSimpleCommand);
  888.     }
  889.     break;
  890.      case CpShow:
  891.     if (strcmp(getItemCommand(panel->editedItem), "SHOW_ALL")!=0) {
  892.         changeItemCommand(panel->editedItem, "SHOW_ALL");
  893.         updateForItemType(panel, TSimpleCommand);
  894.     }
  895.     break;
  896.      case CpExit:
  897.     if (strcmp(getItemCommand(panel->editedItem), "EXIT")!=0) {
  898.         changeItemCommand(panel->editedItem, "EXIT");
  899.         updateForItemType(panel, TExit);
  900.     }
  901.     if (WMGetButtonSelected(panel->noconfirmB))
  902.         changeItemParameter(panel->editedItem, "QUICK");
  903.     else
  904.         changeItemParameter(panel->editedItem, "");
  905.     break;
  906.      case CpShutdown:
  907.     if (strcmp(getItemCommand(panel->editedItem), "SHUTDOWN")!=0) {
  908.         changeItemCommand(panel->editedItem, "SHUTDOWN");
  909.         updateForItemType(panel, TExit);
  910.     }
  911.     if (WMGetButtonSelected(panel->noconfirmB))
  912.         changeItemParameter(panel->editedItem, "QUICK");
  913.     else
  914.         changeItemParameter(panel->editedItem, "");
  915.     break;
  916.      case CpRestartWM:
  917.     changeItemCommand(panel->editedItem, "RESTARTW");
  918.     updateForItemType(panel, TRestartWM);
  919.     break;
  920.      case CpRestart:
  921.     changeItemCommand(panel->editedItem, "RESTART");
  922.     updateForItemType(panel, TRestart);
  923.     tmp = WMGetTextFieldText(panel->proT);
  924.     changeItemParameter(panel->editedItem, tmp);
  925.     free(tmp);
  926.     break;
  927.      case CpSaveSession:
  928.     if (strcmp(getItemCommand(panel->editedItem), "SAVE_SESSION")!=0) {
  929.         changeItemCommand(panel->editedItem, "SAVE_SESSION");
  930.         updateForItemType(panel, TSimpleCommand);
  931.     }
  932.     break;
  933.      case CpClearSession:
  934.     if (strcmp(getItemCommand(panel->editedItem), "CLEAR_SESSION")!=0) {
  935.         changeItemCommand(panel->editedItem, "CLEAR_SESSION");
  936.         updateForItemType(panel, TSimpleCommand);
  937.     }
  938.     break;
  939.      case CpRefresh:
  940.     if (strcmp(getItemCommand(panel->editedItem), "REFRESH")!=0) {
  941.         changeItemCommand(panel->editedItem, "REFRESH");
  942.         updateForItemType(panel, TSimpleCommand);
  943.     }
  944.     break;
  945.      case CpInfo:
  946.     if (strcmp(getItemCommand(panel->editedItem), "INFO_PANEL")!=0) {
  947.         changeItemCommand(panel->editedItem, "INFO_PANEL");
  948.         updateForItemType(panel, TSimpleCommand);
  949.     }
  950.     break;
  951.      case CpLegal:
  952.     if (strcmp(getItemCommand(panel->editedItem), "LEGAL_PANEL")!=0) {
  953.         changeItemCommand(panel->editedItem, "LEGAL_PANEL");
  954.         updateForItemType(panel, TSimpleCommand);
  955.     }
  956.     break;
  957.     }
  958. }
  959.  
  960.  
  961.  
  962.  
  963.  
  964. static char*
  965. captureShortcut(Display *dpy, _Panel *panel)
  966. {
  967.     XEvent ev;
  968.     KeySym ksym;
  969.     char buffer[64];
  970.     char *key = NULL;
  971.  
  972.     while (panel->capturing) {
  973.         XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
  974.     WMNextEvent(dpy, &ev);
  975.     if (ev.type==KeyPress && ev.xkey.keycode!=0) {
  976.         ksym = XKeycodeToKeysym(dpy, ev.xkey.keycode, 0);
  977.         if (!IsModifierKey(ksym)) {
  978.         key=XKeysymToString(ksym);
  979.         panel->capturing = 0;
  980.         break;
  981.         }
  982.     }
  983.     WMHandleEvent(&ev);
  984.     }
  985.     
  986.     if (!key)
  987.     return NULL;
  988.     
  989.     buffer[0] = 0;
  990.     
  991.     if (ev.xkey.state & ControlMask) {
  992.     strcat(buffer, "Control+");
  993.     } 
  994.     if (ev.xkey.state & ShiftMask) {
  995.     strcat(buffer, "Shift+");
  996.     } 
  997.     if (ev.xkey.state & Mod1Mask) {
  998.     strcat(buffer, "Mod1+");
  999.     } 
  1000.     if (ev.xkey.state & Mod2Mask) {
  1001.     strcat(buffer, "Mod2+");
  1002.     } 
  1003.     if (ev.xkey.state & Mod3Mask) {
  1004.     strcat(buffer, "Mod3+");
  1005.     } 
  1006.     if (ev.xkey.state & Mod4Mask) {
  1007.     strcat(buffer, "Mod4+");
  1008.     } 
  1009.     if (ev.xkey.state & Mod5Mask) {
  1010.     strcat(buffer, "Mod5+");
  1011.     }
  1012.     strcat(buffer, key);
  1013.     
  1014.     return wstrdup(buffer);
  1015. }
  1016.  
  1017.  
  1018. static void
  1019. captureClick(WMWidget *w, void *data)
  1020. {
  1021.     _Panel *panel = (_Panel*)data;
  1022.     Display *dpy = WMScreenDisplay(WMWidgetScreen(panel->win));
  1023.     char *shortcut;
  1024.     
  1025.     if (!panel->capturing) {
  1026.     panel->capturing = 1;
  1027.     WMSetButtonText(w, _("Cancel"));
  1028.     XGrabKeyboard(dpy, WMWidgetXID(panel->win), True, GrabModeAsync,
  1029.               GrabModeAsync, CurrentTime);
  1030.     shortcut = captureShortcut(dpy, panel);
  1031.     if (shortcut) {
  1032.         WMSetTextFieldText(panel->shoT, shortcut);
  1033.         changeItemShortcut(panel->editedItem, shortcut);
  1034.         panel->unsaved = 1;
  1035.     }
  1036.     free(shortcut);
  1037.     }
  1038.     panel->capturing = 0;
  1039.     WMSetButtonText(w, _("Capture"));
  1040.     XUngrabKeyboard(dpy, CurrentTime);
  1041. }
  1042.  
  1043.  
  1044.  
  1045. static void
  1046. scrolledBrowser(WMBrowserDelegate *self, WMBrowser *sender)
  1047. {
  1048.     _Panel *panel = (_Panel*)self->data;
  1049.     int column;
  1050.     proplist_t item;
  1051.  
  1052.     column = WMGetBrowserFirstVisibleColumn(sender);
  1053.  
  1054.     item = getSubmenuInColumn(panel, column);
  1055.     WMSetTextFieldText(panel->tit1T, getItemTitle(item));
  1056.  
  1057.     item = getSubmenuInColumn(panel, column + 1);
  1058.     if (item) {
  1059.     WMSetTextFieldText(panel->tit2T, getItemTitle(item));
  1060.     }
  1061.     panel->scrolledBrowser = 1;
  1062. }
  1063.  
  1064.  
  1065. static void
  1066. confirmClicked(WMWidget *w, void *data)
  1067. {
  1068.     _Panel *panel = (_Panel*)data;
  1069.     
  1070.     if (WMGetButtonSelected(panel->noconfirmB)) {
  1071.     changeItemParameter(panel->editedItem, "QUICK");
  1072.     } else {
  1073.     changeItemParameter(panel->editedItem, "");
  1074.     }
  1075.     panel->unsaved = 1;
  1076. }
  1077.  
  1078.  
  1079.  
  1080. static void
  1081. openGuru(WMWidget *w, void *data)
  1082. {
  1083.     _Panel *panel = (_Panel*)data;
  1084.     char *def;
  1085.     char *path, *cmd;
  1086.     
  1087.     def = OpenMenuGuru(GetWindow(panel));
  1088.     if (def) {
  1089.     changeItemParameter(panel->editedItem, def);
  1090.     splitOpenMenuParameter(def, &path, &cmd);
  1091.     free(def);
  1092.     WMSetTextFieldText(panel->pathT, path);
  1093.     if (path) 
  1094.         free(path);
  1095.  
  1096.     WMSetTextFieldText(panel->proT, cmd);
  1097.     if (cmd)
  1098.         free(cmd);
  1099.     panel->unsaved = 1;
  1100.     }
  1101. }
  1102.  
  1103.  
  1104. static void
  1105. createPanel(_Panel *p)
  1106. {
  1107.     _Panel *panel = (_Panel*)p;
  1108.     
  1109.     
  1110.     panel->frame = WMCreateFrame(panel->win);
  1111.     WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
  1112.     WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
  1113.  
  1114.     panel->cmd1P = WMCreatePopUpButton(panel->frame);
  1115.     WMSetPopUpButtonAction(panel->cmd1P, performCommand, panel);
  1116.     WMResizeWidget(panel->cmd1P, 144, 20);
  1117.     WMMoveWidget(panel->cmd1P, 15, 15);
  1118.     WMSetPopUpButtonPullsDown(panel->cmd1P, True);
  1119.     WMSetPopUpButtonText(panel->cmd1P, _("Commands"));
  1120.     WMAddPopUpButtonItem(panel->cmd1P, _("Add Command"));
  1121.     WMAddPopUpButtonItem(panel->cmd1P, _("Add Submenu"));
  1122.     WMAddPopUpButtonItem(panel->cmd1P, _("Add External Menu"));
  1123.     WMAddPopUpButtonItem(panel->cmd1P, _("Add Workspace Menu"));
  1124.     WMAddPopUpButtonItem(panel->cmd1P, _("Remove Item"));
  1125.     WMAddPopUpButtonItem(panel->cmd1P, _("Cut Item"));
  1126.     WMAddPopUpButtonItem(panel->cmd1P, _("Copy Item"));
  1127.     WMAddPopUpButtonItem(panel->cmd1P, _("Paste Item"));
  1128.     
  1129.     panel->cmd2P = WMCreatePopUpButton(panel->frame);
  1130.     WMSetPopUpButtonAction(panel->cmd2P, performCommand, panel);
  1131.     WMResizeWidget(panel->cmd2P, 144, 20);
  1132.     WMMoveWidget(panel->cmd2P, 164, 15);
  1133.     WMSetPopUpButtonPullsDown(panel->cmd2P, True);
  1134.     WMSetPopUpButtonText(panel->cmd2P, _("Commands"));
  1135.     WMAddPopUpButtonItem(panel->cmd2P, _("Add Command"));
  1136.     WMAddPopUpButtonItem(panel->cmd2P, _("Add Submenu"));
  1137.     WMAddPopUpButtonItem(panel->cmd2P, _("Add External Menu"));
  1138.     WMAddPopUpButtonItem(panel->cmd2P, _("Add Workspace Menu"));
  1139.     WMAddPopUpButtonItem(panel->cmd2P, _("Remove Item"));
  1140.     WMAddPopUpButtonItem(panel->cmd2P, _("Cut Item"));
  1141.     WMAddPopUpButtonItem(panel->cmd2P, _("Copy Item"));
  1142.     WMAddPopUpButtonItem(panel->cmd2P, _("Paste Item"));
  1143.     
  1144.     panel->tit1T = WMCreateTextField(panel->frame);
  1145.     WMResizeWidget(panel->tit1T, 144, 20);
  1146.     WMMoveWidget(panel->tit1T, 15, 40);
  1147.     WMAddNotificationObserver(changedTitle, panel, WMTextDidChangeNotification,
  1148.                   panel->tit1T);
  1149.     
  1150.     panel->tit2T = WMCreateTextField(panel->frame);
  1151.     WMResizeWidget(panel->tit2T, 144, 20);
  1152.     WMMoveWidget(panel->tit2T, 164, 40);
  1153.     WMAddNotificationObserver(changedTitle, panel, WMTextDidChangeNotification,
  1154.                   panel->tit2T);
  1155.  
  1156.     panel->browser = WMCreateBrowser(panel->frame);
  1157.     WMSetBrowserTitled(panel->browser, False);
  1158.     WMResizeWidget(panel->browser, 295, 160);
  1159.     WMMoveWidget(panel->browser, 15, 65);
  1160.     
  1161.     browserDelegate.data = panel;
  1162.     
  1163.     WMSetBrowserDelegate(panel->browser, &browserDelegate);
  1164.     WMHangData(panel->browser, panel);
  1165.     WMSetBrowserPathSeparator(panel->browser, "\r");
  1166.     WMSetBrowserAction(panel->browser, browserClick, panel);
  1167.  
  1168.     /**/
  1169.  
  1170.     panel->labF = WMCreateFrame(panel->frame);
  1171.     WMResizeWidget(panel->labF, 190, 50);
  1172.     WMMoveWidget(panel->labF, 320, 10);
  1173.     WMSetFrameTitle(panel->labF, _("Label"));
  1174.  
  1175.     panel->labT = WMCreateTextField(panel->labF);
  1176.     WMResizeWidget(panel->labT, 170, 20);
  1177.     WMMoveWidget(panel->labT, 10, 20);
  1178.     WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification,
  1179.                   panel->labT);
  1180.     
  1181.     WMMapSubwidgets(panel->labF);
  1182.     
  1183.     panel->cmdF = WMCreateFrame(panel->frame);
  1184.     WMResizeWidget(panel->cmdF, 190, 50);
  1185.     WMMoveWidget(panel->cmdF, 320, 65);
  1186.     WMSetFrameTitle(panel->cmdF, _("Command"));
  1187.  
  1188.     panel->cmdP = WMCreatePopUpButton(panel->cmdF);
  1189.     WMResizeWidget(panel->cmdP, 170, 20);
  1190.     WMMoveWidget(panel->cmdP, 10, 20);
  1191.     WMAddPopUpButtonItem(panel->cmdP, _("Run Program"));
  1192.     WMAddPopUpButtonItem(panel->cmdP, _("Execute Shell Command"));
  1193.     WMAddPopUpButtonItem(panel->cmdP, _("Arrange Icons"));
  1194.     WMAddPopUpButtonItem(panel->cmdP, _("Hide Others"));
  1195.     WMAddPopUpButtonItem(panel->cmdP, _("Show All Windows"));
  1196.     WMAddPopUpButtonItem(panel->cmdP, _("Exit WindowMaker"));
  1197.     WMAddPopUpButtonItem(panel->cmdP, _("Exit X Session"));
  1198.     WMAddPopUpButtonItem(panel->cmdP, _("Start Window Manager"));
  1199.     WMAddPopUpButtonItem(panel->cmdP, _("Restart WindowMaker"));
  1200.     WMAddPopUpButtonItem(panel->cmdP, _("Save Session"));
  1201.     WMAddPopUpButtonItem(panel->cmdP, _("Clear Session"));
  1202.     WMAddPopUpButtonItem(panel->cmdP, _("Refresh Screen"));
  1203.     WMAddPopUpButtonItem(panel->cmdP, _("Info Panel"));
  1204.     WMAddPopUpButtonItem(panel->cmdP, _("Legal Panel"));
  1205.     WMSetPopUpButtonAction(panel->cmdP, changedCommand, panel);
  1206.     
  1207.     WMMapSubwidgets(panel->cmdF);
  1208.     
  1209.     panel->infoL = WMCreateLabel(panel->frame);
  1210.     WMResizeWidget(panel->infoL, 190, 50);
  1211.     WMMoveWidget(panel->infoL, 320, 65);
  1212.     WMSetLabelText(panel->infoL, _("Open workspace menu"));
  1213.     WMSetLabelRelief(panel->infoL, WRGroove);
  1214.     WMSetLabelTextAlignment(panel->infoL, WACenter);
  1215.  
  1216.     panel->noconfirmB = WMCreateSwitchButton(panel->frame);
  1217.     WMResizeWidget(panel->noconfirmB, 190, 50);
  1218.     WMMoveWidget(panel->noconfirmB, 320, 120);
  1219.     WMSetButtonText(panel->noconfirmB, _("No confirmation panel"));
  1220.     WMSetButtonAction(panel->noconfirmB, confirmClicked, panel);
  1221.  
  1222.     panel->pathF = WMCreateFrame(panel->frame);
  1223.     WMResizeWidget(panel->pathF, 190, 50);
  1224.     WMMoveWidget(panel->pathF, 320, 65);
  1225.     WMSetFrameTitle(panel->pathF, _("Menu Path/Directory List"));
  1226.     
  1227.     panel->pathT = WMCreateTextField(panel->pathF);
  1228.     WMResizeWidget(panel->pathT, 170, 20);
  1229.     WMMoveWidget(panel->pathT, 10, 20);
  1230.     WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification,
  1231.                   panel->pathT);
  1232.  
  1233.     WMMapSubwidgets(panel->pathF);
  1234.  
  1235.     panel->proF = WMCreateFrame(panel->frame);
  1236.     WMResizeWidget(panel->proF, 190, 50);
  1237.     WMMoveWidget(panel->proF, 320, 120);
  1238.     WMSetFrameTitle(panel->proF, _("Program to Run"));
  1239.     
  1240.     panel->proT = WMCreateTextField(panel->proF);
  1241.     WMResizeWidget(panel->proT, 170, 20);
  1242.     WMMoveWidget(panel->proT, 10, 20);
  1243.     WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification,
  1244.                   panel->proT);
  1245.  
  1246.     WMMapSubwidgets(panel->proF);
  1247.  
  1248.     panel->shoF = WMCreateFrame(panel->frame);
  1249.     WMResizeWidget(panel->shoF, 190, 50);
  1250.     WMMoveWidget(panel->shoF, 320, 175);
  1251.     WMSetFrameTitle(panel->shoF, _("Shortcut"));
  1252.     
  1253.     panel->shoT = WMCreateTextField(panel->shoF);
  1254.     WMResizeWidget(panel->shoT, 95, 20);
  1255.     WMMoveWidget(panel->shoT, 10, 20);
  1256.     WMAddNotificationObserver(changedItem, panel, WMTextDidChangeNotification,
  1257.                   panel->shoT);
  1258.     
  1259.     panel->shoB = WMCreateCommandButton(panel->shoF);
  1260.     WMResizeWidget(panel->shoB, 70, 24);
  1261.     WMMoveWidget(panel->shoB, 110, 18);
  1262.     WMSetButtonText(panel->shoB, _("Capture"));
  1263.     WMSetButtonAction(panel->shoB, captureClick, panel);
  1264.  
  1265.     WMMapSubwidgets(panel->shoF);
  1266.     
  1267.     panel->guruB = WMCreateCommandButton(panel->frame);
  1268.     WMResizeWidget(panel->guruB, 180, 24);
  1269.     WMMoveWidget(panel->guruB, 325, 190);
  1270.     WMSetButtonText(panel->guruB, _("Ask help to the Guru"));
  1271.     WMSetButtonAction(panel->guruB, openGuru, panel);
  1272.  
  1273.     WMRealizeWidget(panel->frame);
  1274.     WMMapSubwidgets(panel->frame);
  1275.  
  1276.     showData(panel);
  1277. }
  1278.  
  1279.  
  1280.  
  1281.  
  1282. static proplist_t
  1283. preProcessMenu(proplist_t menu, int *hasWSMenu)
  1284. {
  1285.     proplist_t pmenu;
  1286.     proplist_t item;
  1287.     int i;
  1288.  
  1289.     pmenu = PLDeepCopy(menu);
  1290.     if (PLGetNumberOfElements(pmenu)==1) {
  1291.     return pmenu;
  1292.     }
  1293.     for (i=1; i<PLGetNumberOfElements(pmenu); i++) {
  1294.     item = PLGetArrayElement(pmenu, i);
  1295.     if (isMenu(item)) {
  1296.         PLInsertArrayElement(pmenu, preProcessMenu(item, hasWSMenu), i);
  1297.         PLRemoveArrayElement(pmenu, i+1);
  1298.         PLRelease(item);
  1299.     } else if (strcmp(getItemCommand(item), "RESTART")==0) {
  1300.         if (getItemShortcut(item)) {
  1301.         if (PLGetNumberOfElements(item) == 4) {
  1302.             changeItemCommand(item, "RESTARTW");
  1303.             PLAppendArrayElement(item, PLMakeString(""));
  1304.         }
  1305.         } else {
  1306.         if (PLGetNumberOfElements(item) == 2) {
  1307.             changeItemCommand(item, "RESTARTW");
  1308.             PLAppendArrayElement(item, PLMakeString(""));
  1309.         }
  1310.         }
  1311.     } else {
  1312.         if (strcmp(getItemCommand(item),"WORKSPACE_MENU")==0)
  1313.         *hasWSMenu = 1;
  1314.         if (getItemShortcut(item)) {
  1315.         if (PLGetNumberOfElements(item) == 4)
  1316.             PLAppendArrayElement(item, PLMakeString(""));
  1317.         } else {
  1318.         if (PLGetNumberOfElements(item) == 2)
  1319.             PLAppendArrayElement(item, PLMakeString(""));
  1320.         }
  1321.     }
  1322.     }
  1323.  
  1324.     return pmenu;
  1325. }
  1326.  
  1327.  
  1328.  
  1329. static proplist_t
  1330. postProcessMenu(proplist_t menu)
  1331. {
  1332.     proplist_t pmenu;
  1333.     proplist_t item;
  1334.     int i;
  1335.     int count;
  1336.  
  1337.     pmenu = PLDeepCopy(menu);
  1338.     if (PLGetNumberOfElements(pmenu)==1) {
  1339.     return pmenu;
  1340.     }
  1341.     count = PLGetNumberOfElements(pmenu);
  1342.     for (i=1; i<count; i++) {
  1343.     char *cmd;
  1344.     item = PLGetArrayElement(pmenu, i);
  1345.     if (isMenu(item)) {
  1346.         PLInsertArrayElement(pmenu, postProcessMenu(item), i);
  1347.         PLRemoveArrayElement(pmenu, i+1);
  1348.         PLRelease(item);
  1349.     } else {
  1350.         cmd = getItemCommand(item);
  1351.         if (strcmp(cmd, "RESTARTW")==0) {
  1352.         changeItemCommand(item, "RESTART");
  1353.         removeParameter(item);
  1354.         } else if (strcmp(cmd, "EXEC")==0 || strcmp(cmd, "SHEXEC")==0 || 
  1355.                strcmp(cmd, "OPEN_MENU")==0) {
  1356.         /* do nothing */
  1357.         } else if (strcmp(cmd, "RESTART")==0 || strcmp(cmd, "SHUTDOWN")==0
  1358.                || strcmp(cmd, "EXIT")==0) {
  1359.         char *tmp = getItemParameter(item);
  1360.         if (tmp && strlen(tmp)==0)
  1361.             removeParameter(item);
  1362.         } else {
  1363.         removeParameter(item);
  1364.         }
  1365.     }
  1366.     }
  1367.  
  1368.     return pmenu;
  1369. }
  1370.  
  1371.  
  1372. static proplist_t
  1373. getDefaultMenu(_Panel *panel, int *hasWSMenu)
  1374. {
  1375.     proplist_t menu, pmenu;
  1376.     char *menuPath, *gspath;
  1377.  
  1378.     gspath = wusergnusteppath();
  1379.  
  1380.     menuPath = wmalloc(strlen(gspath)+128);
  1381.     /* if there is a localized plmenu for the tongue put it's filename here */
  1382.     sprintf(menuPath, _("%s/Library/WindowMaker/plmenu"), gspath);
  1383.  
  1384.     menu = PLGetProplistWithPath(menuPath);
  1385.     if (!menu) {
  1386.     wwarning("%s:could not read property list menu", menuPath);
  1387.  
  1388.     if (strcmp("%s/Library/WindowMaker/plmenu",
  1389.            _("%s/Library/WindowMaker/plmenu"))!=0) {
  1390.  
  1391.         sprintf(menuPath, "%s/Library/WindowMaker/plmenu", gspath);
  1392.         menu = PLGetProplistWithPath(menuPath);
  1393.         wwarning("%s:could not read property list menu", menuPath);
  1394.     }
  1395.     if (!menu) {
  1396.         char buffer[512];
  1397.  
  1398.         sprintf(buffer, _("Could not open default menu from '%s'"),
  1399.             menuPath);
  1400.         WMRunAlertPanel(WMWidgetScreen(panel->win), panel->win,
  1401.                 _("Error"), buffer,    _("OK"), NULL, NULL);
  1402.     }
  1403.     }
  1404.  
  1405.     free(menuPath);
  1406.  
  1407.     if (menu) {
  1408.     pmenu = preProcessMenu(menu, hasWSMenu);
  1409.     PLRelease(menu);
  1410.     } else {
  1411.     pmenu = NULL;
  1412.     }
  1413.  
  1414.     return pmenu;
  1415. }
  1416.  
  1417.  
  1418. static void
  1419. showData(_Panel *panel)
  1420. {
  1421.     char *gspath;
  1422.     char *menuPath;
  1423.     proplist_t menu, pmenu, plPath;
  1424.     int hasWSMenu = 0;
  1425.  
  1426.     gspath = wusergnusteppath();
  1427.  
  1428.     menuPath = wmalloc(strlen(gspath)+32);
  1429.     strcpy(menuPath, gspath);
  1430.     strcat(menuPath, "/Defaults/WMRootMenu");
  1431.  
  1432.     menu = PLGetProplistWithPath(menuPath);
  1433.     pmenu = NULL;
  1434.  
  1435.     if (!menu || !PLIsArray(menu)) {
  1436.     if (AskMenuCopy(panel->win)) {
  1437.         panel->dontSave = 0;
  1438.         panel->unsaved = 1;
  1439.  
  1440.         pmenu = getDefaultMenu(panel, &hasWSMenu);
  1441.     } else {
  1442.         WMSetPopUpButtonEnabled(panel->cmd1P, False);
  1443.         WMSetPopUpButtonEnabled(panel->cmd2P, False);
  1444.         panel->dontSave = 1;
  1445.     }
  1446.     if (!pmenu) {
  1447.         pmenu = PLMakeArrayFromElements(PLMakeString("Applications"),
  1448.                         NULL);
  1449.     }
  1450.     } else {
  1451.     pmenu = preProcessMenu(menu, &hasWSMenu);
  1452.     }
  1453.     plPath = PLMakeString(menuPath);
  1454.     free(menuPath);
  1455.     PLSetFilename(pmenu, plPath);
  1456.     PLRelease(plPath);
  1457.  
  1458.     if (menu)
  1459.         PLRelease(menu);
  1460.  
  1461.     if (panel->itemClipboard) {
  1462.     PLRelease(panel->itemClipboard);
  1463.     panel->itemClipboard = NULL;
  1464.     }
  1465.     panel->menu = pmenu;
  1466.     panel->editedItem = NULL;
  1467.     panel->capturing = 0;
  1468.  
  1469.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CPaste, False);
  1470.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CPaste, False);
  1471.     if (hasWSMenu) {
  1472.     WMSetPopUpButtonItemEnabled(panel->cmd1P, CAddWorkspace, False);
  1473.     WMSetPopUpButtonItemEnabled(panel->cmd2P, CAddWorkspace, False);
  1474.     }
  1475.     WMLoadBrowserColumnZero(panel->browser);
  1476.  
  1477.     updateForItemType(panel, TNothing);
  1478. }
  1479.  
  1480.  
  1481. static void
  1482. storeData(_Panel *panel)
  1483. {
  1484.     proplist_t menu;
  1485.  
  1486.     if (!panel->unsaved || panel->dontSave)
  1487.     return;
  1488.     panel->unsaved = 0;
  1489.  
  1490.     menu = postProcessMenu(panel->menu);
  1491.  
  1492.     PLSetFilename(menu, PLGetFilename(panel->menu));
  1493.  
  1494.     PLSave(menu, YES);
  1495.     
  1496.     PLRelease(menu);
  1497. }
  1498.  
  1499.  
  1500. Panel*
  1501. InitMenu(WMScreen *scr, WMWindow *win)
  1502. {
  1503.     _Panel *panel;
  1504.     
  1505.     panel = wmalloc(sizeof(_Panel));
  1506.     memset(panel, 0, sizeof(_Panel));
  1507.  
  1508.     panel->sectionName = _("Applications Menu Definition");
  1509.  
  1510.     panel->description = _("Edit the menu for launching applications.");
  1511.  
  1512.     panel->win = win;
  1513.  
  1514.     panel->callbacks.createWidgets = createPanel;
  1515.     panel->callbacks.updateDomain = storeData;
  1516.     
  1517.     AddSection(panel, ICON_FILE);
  1518.  
  1519.     return panel;
  1520. }
  1521.